/**
 * Created by 雷洪飞 on 2017/8/17.
 * @description: 用于下载excel类似的csv文件
 */


export class DownLoad {
  private static csvSeparator = ',';


  /**
   * 导出数据
   * @param dt datatable
   * @param data 需要导出的数据
   * @param fileName 文件名称
   */
  static exportCSV(dt: any, data, fileName: string) {
    const thisD = dt;
    // 循环得到头
    let csv = DownLoad.getHeader(dt.columns, true);
    // 得到内容
    data.forEach((record, i) => {
      csv += '\n';
      for (let te = 0 ; te < thisD.columns.length ; te++) {
        if (thisD.columns[te].field) {
          csv += '"' + DownLoad.resolveFieldData(record, thisD.columns[te].field) + '"';
          if (te < (thisD.columns.length - 1)) {
            csv += thisD.csvSeparator;
          }
        }
      }
    });
    // 导出数据
    DownLoad.export(csv, fileName);
  }

  /**
   *   带条件的数据导出，将数据库的特殊字符表示为
   *   正常字符导出
   * @param dt datatables
   * @param data 需要导出的数据
   * @param fileName 文件名称
   * @param condition 导出数据的格式转换
   * 例如：1.下载的数据有一些字符表示，怎么将他们转化成别人看得懂的数据勒
   *    {
   *      status:{
   *        y:'审核通过';
   *        n:'审核不通过';
   *      }
   *    }
   */
  static exportCSVForCondition(dt: any, data, fileName: string, condition) {
    const thisD = dt;
    // 循环得到头
    let csv = DownLoad.getHeader(dt.columns, true);
    // //得到内容
    data.forEach((record, i) => {
      csv += '\n';
      for (let te = 0 ; te < thisD.columns.length ; te++) {
        if (thisD.columns[te].field) {
          const temp = condition[thisD.columns[te].field];
          if (temp) {
            // 说明有这个元素，那么就需要根据值来判断内容,得到了返回数据的内容
            const t = temp[record[thisD.columns[te].field]];
            // 取到了值了
            csv += '"' + t + '"';
          } else {
            csv += '"' + DownLoad.resolveFieldData(record, thisD.columns[te].field) + '"';
          }
          if (te < (thisD.columns.length - 1)) {
            csv += thisD.csvSeparator;
          }
        }
      }
    });
    // 导出数据
    DownLoad.export(csv, fileName);
  }

  /**
   * 文件上传失败的数据，进行数据导出
   * @param data  数组数据 数据
   * @param fileName 文件名称 导入教师失败数据
   * @param firstRowName 第一列数据名称 ['姓名','性别']
   * @param field 导出的列的名称  ['user','sex']
   * @param condition 输出条件
   */
  public static uploadExcelDownload(data: any, fileName: string, firstRowName: any, field: any, condition: any) {
    let csv = DownLoad.getHeader(firstRowName, false);
    // 循环真实数据
    data.forEach((item) => {
      csv += '\n';
      // 循环需要导出的字段
      field.forEach((temp, index) => {
        // 得到该字段
        //  取出要根据条件导出的数据
        const con = condition[temp];
        if (con) {
          // 说明需要进行条件导出
          csv += '"' + this.checkNull(con[item[temp]]) + '"';
        } else {
          let text = this.checkNull(item[temp]);
          let o = item;
          temp.split('.').forEach(t => {
            if (typeof (o[t]) !== 'object') {
              text = this.checkNull(o[t]);
            } else {
              o = this.checkNull(o[t]);
            }
          });

          csv += '"' + text + '"';
        }
        if (index < field.length - 1) {
          csv += DownLoad.csvSeparator;
        }
      });
    });
    // 导出数据
    DownLoad.export(csv, fileName);
  }

  /**
   * 检查是否为空或者为undefined
   * @param str 需要判断的字段
   * @returns string 字符串
   */
  private static checkNull(str): string {
    if (typeof (str) === 'undefined' || str === null) {
      return '';
    } else {
      return str;
    }
  }

  /**
   * 导出数据
   * @param csv  数据内容
   * @param fileName 文件名称
   */
  static export(csv, fileName) {
    const blob = new Blob([csv], {
      type: 'text/csv;charset=utf-8;'
    });
    if (window.navigator.msSaveOrOpenBlob) {
      navigator.msSaveOrOpenBlob(blob, fileName + '.csv');
    } else {
      const link = document.createElement('a');
      link.style.display = 'none';
      document.body.appendChild(link);
      if (link.download !== undefined) {
        link.setAttribute('href', URL.createObjectURL(blob));
        link.setAttribute('download', fileName + '.csv');
        link.click();
      } else {
        csv = 'data:text/csv;charset=utf-8,' + csv;
        window.open(encodeURI(csv));
      }
      document.body.removeChild(link);
    }
  }

  /**
   * 从数组里面得到数据
   * @param data 数据
   * @param field 字段
   */
  private static resolveFieldData(data, field) {
    if (data && field) {
      if (field.indexOf('.') === -1) {
        return data[field] === null ? '' : data[field];
      } else {
        const fields = field.split('.');
        let value = data;
        for (let i = 0, len = fields.length ; i < len ; ++i) {
          if (value === null) {
            return '';
          }
          value = value[fields[i]];
        }
        return value;
      }
    } else {
      return '';
    }
  }

  /**
   * 得到导出数据的头部
   * @param headers 头数据
   * @param flag 是导出，还是失败后的下载
   */
  private static getHeader(headers, flag: boolean): string {
    let csv = '\ufeff';
    // 循环得到头
    for (let i = 0 ; i < headers.length ; i++) {
      if (!flag) {
        if (headers[i]) {
          csv += '"' + (headers[i]) + '"';
          if (i < (headers.length - 1)) {
            csv += this.csvSeparator;
          }
        }
      } else {
        if (headers[i].field) {
          csv += '"' + (headers[i].header || headers[i].field) + '"';
          if (i < (headers.length - 1)) {
            csv += this.csvSeparator;
          }
        }
      }
    }
    return csv;
  }

}
